package logger

import (
	"os"
	"path"
	"fmt"
	"time"
	"strconv"

    "github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"

	"ginframe/db/model"
	"ginframe/config"
)

var (
	conf *config.Config
)

func init () {
	conf = config.GetConfig()
}

func LogMiddleWare() gin.HandlerFunc {
	var (
		logFilePath = conf.Logger.Path //文件存储路径
		logFileName = conf.Logger.Filename //日志文件名
	)
	// 日志文件
	fileName := path.Join(logFilePath, logFileName)
	// 写入文件
	file, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("打开/写入文件失败", err)
		return nil
	}
	// 实例化
	logger := logrus.New()
	// 日志级别
	logger.SetLevel(logrus.DebugLevel)
	// 设置输出
	logger.Out = file
	// 设置 rotatelogs,实现文件分割
	logWriter, err := rotatelogs.New(
		// 分割后的文件名称
		fileName+".%Y%m%d.log",
		// 生成软链，指向最新日志文件
		rotatelogs.WithLinkName(fileName),
		// 设置最大保存时间(7天)
		rotatelogs.WithMaxAge(time.Duration(conf.Logger.MixAge) * time.Hour), //以hour为单位的整数
		// 设置日志切割时间间隔(1天)
		rotatelogs.WithRotationTime(time.Duration(conf.Logger.RotationTime) * time.Hour),
	)
	// hook机制的设置
	writerMap := lfshook.WriterMap{
		logrus.InfoLevel:  logWriter,
		logrus.FatalLevel: logWriter,
		logrus.DebugLevel: logWriter,
		logrus.WarnLevel:  logWriter,
		logrus.ErrorLevel: logWriter,
		logrus.PanicLevel: logWriter,
	}
	//给logrus添加hook
	logger.AddHook(lfshook.NewHook(writerMap, &logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	}))

	return func(c *gin.Context) {
		c.Next()
		// 打印日志
		logger.WithFields(logrus.Fields{
			"status_code": c.Writer.Status(), //状态码
			"client_ip":   c.ClientIP(), //请求ip
			"req_method":  c.Request.Method, //请求方式
			"req_uri":     c.Request.RequestURI, //请求路由
		}).Info()
		// 插入mysql
		mixlog := model.Mixlog{
			Path: c.Request.RequestURI,
			Method: c.Request.Method,
			Status: strconv.Itoa(c.Writer.Status()),
			Ip: c.ClientIP(),
		}
		model.InsertMixlog(mixlog)
	}
}
